﻿using System;
using System.Threading;
using System.Text;
using System.Net;
using System.Windows.Forms;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;

namespace Boxie
{
    class BoxieThreadLib
    {
        private delegate void Del_CheckForUpdates_Done(string buildnum);
        private delegate void Del_GetIP_Done(string ip);
        private delegate void Del_ShowDrawingForm_Done(string ip);
        private delegate void Del_UpdateDrawingPadFromStream_Done(byte[] iData);
        private delegate void Del_ShowTextEditor_Done(string nothing);
        private delegate void Del_UpdateTextEditor_Done(string t);
        private delegate void Del_HideTextEditor_Done(string nothing);
        private static frmConfig configInstance;
        private static MemoryStream ms = new MemoryStream();

        public static void CheckForUpdates()
        {
            Thread t = new Thread(new ThreadStart(BoxieThreadLib.CheckForUpdates_Thread));
            t.IsBackground = true;
            t.Start();
        }

        public static void CheckForUpdates_Thread()
        {
            try
            {
                WebClient wc = new WebClient();
                string latestBuild = wc.DownloadString("http://www.ethryx.net/boxie/build.txt");
                if (latestBuild != Boxie.Program.BUILD)
                    frmBoxie.instance.BeginInvoke(new Del_CheckForUpdates_Done(BoxieThreadLib.CheckForUpdates_Done),new object[1]{latestBuild});
            }
            catch
            {
            }
        }

        public static void CheckForUpdates_Done(string buildnum)
        {
            DialogResult dr = MessageBox.Show("A new version is available! Would you like to download it now?", "New Version Available", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
            if (dr == DialogResult.Yes)
                frmBoxie.instance.SetTextBox("update", true);
        }

        public static void GetIP(frmConfig f)
        {
            configInstance = f;
            Thread t = new Thread(new ThreadStart(BoxieThreadLib.GetIP_Thread));
            t.IsBackground = true;
            t.Start();
        }

        public static void GetIP_Thread()
        {
            try
            {
                WebClient wc = new WebClient();
                string ip = System.Text.Encoding.ASCII.GetString(wc.DownloadData("http://whatismyip.com/automation/n09230945.asp"));
                frmBoxie.instance.BeginInvoke(new Del_GetIP_Done(BoxieThreadLib.GetIP_Done), new object[1] { ip });
            }
            catch
            {
            }
        }

        public static void GetIP_Done(string ip)
        {
            configInstance.txtIP.Text = ip;
        }

        public static void ShowDrawingForm(string ip)
        {
            try
            {
                frmBoxie.instance.BeginInvoke(new Del_ShowDrawingForm_Done(BoxieThreadLib.ShowDrawingForm_Done), new object[1] { ip });
            }
            catch
            {
            }
        }

        public static void ShowTextEditorForm()
        {
            try
            {
                frmBoxie.instance.BeginInvoke(new Del_ShowTextEditor_Done(BoxieThreadLib.ShowTextEditor_Done), new object[1]{""});
            }
            catch
            {
            }
        }

        public static void ShowTextEditor_Done(string nothing)
        {
            if (Boxie.frmBoxie.instance.fT == null || Boxie.frmBoxie.instance.fT.IsDisposed)
                Boxie.frmBoxie.instance.fT = new frmTextEdit();
            Boxie.frmBoxie.instance.fT.Show();
            Boxie.frmBoxie.instance.fL.add("Text editing session started.", 2);
        }

        public static void HideTextEditor()
        {
            try
            {
                frmBoxie.instance.BeginInvoke(new Del_HideTextEditor_Done(BoxieThreadLib.HideTextEditor_Done), new object[1] { "" });
            }
            catch
            {
            }
        }

        public static void HideTextEditor_Done(string nothing)
        {
            Boxie.frmBoxie.instance.fT.Close();
            Boxie.frmBoxie.instance.fT = null;
            Boxie.frmBoxie.instance.fL.add("Text editing session ended.", 2);
        }

        public static void UpdateTextEditor(string t)
        {
            try
            {
                frmBoxie.instance.BeginInvoke(new Del_UpdateTextEditor_Done(BoxieThreadLib.UpdateTextEditor_Done), new object[1] { t });
            }
            catch
            {
            }
        }

        public static void UpdateTextEditor_Done(string t)
        {
            Boxie.frmBoxie.instance.fT.updateText(t);
        }

        public static void HideDrawingForm()
        {
            try
            {
                frmBoxie.instance.BeginInvoke(new Del_ShowDrawingForm_Done(BoxieThreadLib.ShowDrawingForm_Done), new object[1] { "" });
            }
            catch
            {
            }
        }

        public static void ShowDrawingForm_Done(string ip)
        {
            if (ip != "")
            {
                if (frmBoxie.instance.fD == null)
                    frmBoxie.instance.fD = new frmDrawing();
                frmBoxie.instance.fD.Show();
                frmBoxie.instance.fD.Text = "Drawing with " + ip;
                frmBoxie.instance.fL.add("Drawing session started.", 2);
            }
            else
            {
                frmBoxie.instance.fD.Visible = false;
                frmBoxie.instance.fD.ClearPad();
                frmBoxie.instance.fL.add("Drawing session ended.", 2);
            }
        }

        public static void UpdateDrawingPadFromStream(byte[] iData)
        {
            try
            {
                frmBoxie.instance.BeginInvoke(new Del_UpdateDrawingPadFromStream_Done(BoxieThreadLib.UpdateDrawingPadFromStream_Done), new object[1] { iData });
            }
            catch
            {
            }
        }

        public static unsafe void UpdateDrawingPadFromStream_Done(byte[] iData)
        {
            Graphics.FromImage(frmBoxie.instance.fD.bitDrawingPadRemote).Clear(Color.White);
            BitmapData bData = frmBoxie.instance.fD.bitDrawingPadRemote.LockBits(new Rectangle(new Point(), frmBoxie.instance.fD.bitDrawingPadRemote.Size), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);

            // Copy the bytes to the bitmap object
            Marshal.Copy(iData, 0, bData.Scan0, iData.Length);
            frmBoxie.instance.fD.bitDrawingPadRemote.UnlockBits(bData);

            frmBoxie.instance.fD.DrawingPadUpdate();
        }
    }
}
